#include "client.h"
#include "message.h"

void* client_side(void* arg)
{
        char name[SIZENAME];
        int i, flag_alone=1;
        
        memset(name, '\0', SIZENAME);
        strcpy(name, (char*) arg);
        
        /* Welcome message */
        printf("\n--------------------------------------------------------------------------------\n\n");
        printf("* Welcome to Panda messenger, %s !\n\n", name);
        printf("* To display the help, use the command line \"/help\"\n\n");
        printf("--------------------------------------------------------------------------------\n");
        
        if(adressBook.me.ip[0]=='\0')
        {
                //pas de carnet d'adresse
                printf("* It's your first connection, please enter your ip adress with the command \"/myip <ip>\"\n");
        }
        else
        {
        
                printf("<-- Connecting to PANDA Network... \n");

                
                send_message_all("", CONNECTION);
                sleep(1);
                
                for(i=0;i<adressBook.nbContacts; i++)
                {
                        if(adressBook.contacts[i].connected)
                        {
                                flag_alone=0;
                        }
                }
                
                if (flag_alone)
                {
                        printf("\n* No contacts connected.\n");
                        fflush(stdout);    
                }
        }       
        
        // Boucle de demande d'un message du client
        int quit = 0;
        int cmdc;
        char raw[RAWSIZE];
        // Prompt
        printf("\n> ");
        fflush(stdout);
        
        while (!quit)
        {
                cmdc = -1;
                // On lit le texte que rentre l'utilisateur
                fgets(raw, RAWSIZE, stdin);
                // On parse le message reçu
                if (raw[0] != '\n')
                {                       
                        if (strcmp(raw, "/quit\n") == 0)
                        {
                                // On quitte
                                
                                send_message_all("", DECONNECTION);
                                
                                exit(0);
                        }
                        else if (strncmp(raw, "/add ",5) == 0)
                        {
                                // On parse puis on ajoute un contacte
                                
                                parse_add_contact(raw);
                                
                        }
                        else if (strncmp(raw, "/myip ",6) == 0)
                        {
                                // On parse puis on ajoute l'ip du nouvel utilisateur
                                
                                parse_add_myip(raw);
                                
                        }
                        else if (strncmp(raw, "/help",5) == 0)
                        {
                                // On affiche l'aide
                                
                                printHelp();
                                
                        }
                        else if (strncmp(raw, "/list",5) == 0)
                        {
                                // On affiche la liste des connectés
                                
                                printf("\n* List of connected contacts :\n");
                                flag_alone=1;
                                for(i=0; i<adressBook.nbContacts; i++)
                                {
                                        if(adressBook.contacts[i].connected)
                                        {
                                                flag_alone=0;
                                                printf("*\t %s\n",adressBook.contacts[i].name);
                                        }
                                }
                                printf("\n> ");
                        				fflush(stdout);    
                                
                                if(flag_alone)
                                {
                                        printf("\n* No contacts connected.\n\n> ");
                        								fflush(stdout);    
                                }                                
                        }
                        else if (raw[0] == '@')
                        {
                        				if(adressBook.me.ip[0] == '\0')
                        				{
                        							printf("\n* You must set your ip adress !\n\n> ");
                       								fflush(stdout);    
                        				}
                        				else
                        				{
                                	parse_message(raw);
                                }
                        }               
                        else
                        {
                        			printf("\n* Wrong command line, read \"/help\".\n\n> ");
                        			fflush(stdout);    
                        }
                }
                memset(raw,'\0',RAWSIZE);
                
        }
        return NULL;
}

void parse_message(char* raw)
{
        char name[RAWSIZE];
        char message[RAWSIZE];
        memset(name,'\0',RAWSIZE);
        memset(message,'\0',RAWSIZE);
        
        raw[strlen(raw)-1] = '\0';
        
        // Parsing du name
        int i; 
        for (i=0; i<(int)strlen(raw) && raw[i] != ':'; i++);
        
        if (i == (int)strlen(raw))
        {
                printf("\n* Wrong format : @<receiver>: <message>\n\n> ");
                fflush(stdout);    
                return;
        }
        
        memcpy(name, raw+1, i-1);
        name[i-1]='\0';
        memcpy(message, raw+i+1, (int)strlen(raw)-i);
        
        // Broadcast ?
        if (strcmp(name, "all") == 0)
        {               
                // On vérifie qu'il y'a bien des gens co (sinon c'est inutile)
                for (i=0; i<adressBook.nbContacts && adressBook.contacts[i].connected == 0; i++);
                        
                if (i == adressBook.nbContacts)
                {
                        printf("\n* No contacts connected.\n\n> ");
                        fflush(stdout);    
                        return;
                }
        
                send_message_all(message, STANDARD);
                
              	printf("> ");
     						fflush(stdout);  
                return;
        }
        
        // Nom de groupe ?
        for (i=0; i<adressBook.nbGroups; i++)
        {       
                // Si le nom du groupe correspond
                if (strcmp(adressBook.groups[i].groupName, name) == 0)
                {
                        send_message_group(i, message); 
                                
								      	printf("> ");
						 						fflush(stdout);  
                        return;
                }
        }
        
        // Si le nom de contact existe
        if ((i = searchContactIndex(name))!=-1)
        {
                // Formulation du message
                Message *msg = newMessage();
                
                struct timeval tv;
                gettimeofday(&tv,NULL);
                msg->timestamp = tv.tv_sec;
                /* Message type */
                msg->type = STANDARD;
                /* Sender IP */
                strcpy(msg->ipSender, adressBook.me.ip);
                /* Sender name */
                strcpy(msg->nameSender, adressBook.me.name);
                /* Message contents */
                msg->size = strlen(message)+1;
                msg->message = malloc(RAWSIZE * sizeof(char));
                memset(msg->message, '\0', RAWSIZE);
                strcpy(msg->message,message);
                
                // On lui envoie un message
                Contact c = adressBook.contacts[i];
        
                if(c.connected)
                {
                        // Contact name
                        strcpy(msg->nameReceiver, c.name);
        
                        // Contact ip
                        strcpy(msg->ipReceiver, c.ip);
                        
                        send_message(msg);
                }
                else
                {
                        printf("\n* %s isn't connected.\n\n",c.name);
                }
                
              	printf("> ");
     						fflush(stdout);  
                return;
        }
        
        // Soi-même
        if (strcmp(name, adressBook.me.name) == 0)
        {
                printf("\n# %s@%s : %s\n\n> ", name, name, message);
                fflush(stdout);
                return;
        }
        
        // On arrive ici, on a trouvé personne : on lance la recherche
        printf("\n* Receiver '%s' unknown - Searching.\n\n> ", name);    
        fflush(stdout);      
        
        Message *search_msg;
        
        /* Timestamp */
        struct timeval tv;
        gettimeofday(&tv,NULL);
        
        int sendOneTime = 0;
        
      
        
        /* For each contact ... */
        for (i=0; i<adressBook.nbContacts; i++)
        {     
        		search_msg = newMessage();   		
            search_msg->timestamp = tv.tv_sec;
            search_msg->type = SEARCH;
            strcpy(search_msg->ipSender, adressBook.me.ip);
            strcpy(search_msg->nameSender, adressBook.me.name);
            search_msg->size = strlen(message)+1;
       			search_msg->message = malloc(RAWSIZE * sizeof(char));
            memset(search_msg->message, '\0', RAWSIZE);
            strcpy(search_msg->message,message);
            strcpy(search_msg->nameReceiver, name);
                
        		if(sendOneTime == 0)
        		{
									addMsgReceived(*search_msg);
									sendOneTime = 1;
        				
        		}
    
            Contact c = adressBook.contacts[i];
            
            if(c.connected)
            {
                // Contact ip de transit
                strcpy(search_msg->ipReceiver, c.ip);

                send_message(search_msg);
            }           
        }       
        
        // Done !
}


void parse_add_contact(char* raw)
{
        char name[SIZENAME];
        char ip[SIZEIP];
        memset(name,'\0',SIZENAME);
        memset(ip,'\0',SIZEIP);
        int i; 
        
        // Parsing: "/add <name> <ip>"
        
        raw[strlen(raw)-1] = '\0';
        
        // Parsing du name
        for (i=5; i<(int)strlen(raw) && raw[i] != ' '; i++);
        
        if ((int)strlen(raw)< i+7)
        {
                printf("\n* Wrong format : /add <name> <ip>\n\n> ");
                fflush(stdout);    
                return;
        }
        
        memcpy(name, raw+5, i-5);
        name[i-1]='\0';
        memcpy(ip, raw+i+1, strlen(raw)-i);
        
        if(!isIP(ip))
        {
		        printf("\n\n* Add Contact error : ip %s has not the right format\n\n> ", ip);
		        fflush(stdout);
		        return;
        }
       	else if(strlen(name)>SIZENAME)
        {
		        printf("\n\n* Add Contact error : name %s is too long\n\n> ", name);
		        fflush(stdout);
		        return;
        }
       	else
       	{
       		addContact(name, ip);
       	}
}

void parse_add_myip(char* raw)
{
        char ip[SIZEIP];
        memset(ip,'\0',SIZEIP);
        
        // Parsing: "/myip <ip>"
        
        raw[strlen(raw)-1] = '\0';
        
        if (13 > (int)strlen(raw))
        {
                printf("\n* Wrong format : /myip <ip>\n\n> ");
                fflush(stdout);    
                return;
        }
        
        memcpy(ip, raw+6, strlen(raw)-6);
        ip[strlen(raw)-1]='\0';
        
        
        if(!isIP(ip))
        {
            	printf("\n\n* Add my ip error : ip %s has not the right format\n\n> ", ip);
        		fflush(stdout);
                return;
        }
        else
        {
        		addMyIP(ip);
        }
}

void printHelp ()
{
        printf("\n***** Panda-messenger help *****\n");
        printf("\n*\t/help : display the help\n");
        printf("*\t/list : display all connected contacts\n");
        printf("*\t/myip <ip> : change your ip\n");
        printf("*\t/add <name> <ip> : add a contact to your book\n");
        printf("*\t/quit : quit panda messenger\n");
        printf("*\t@all:<message> : send <message> to all your connected contacts\n");
        printf("*\t@<name>:<message> : send <message> to <name> if he is connected\n\n> ");
        fflush(stdout);    
}

